package com.le.tester.onjava8.l_2_2_8;

import java.io.*;

/**
 * createTime：2023/1/10 17:00
 * description：通过序列化进行深度拷贝,序列化至少比克隆慢一个数量级
 */

class Thing1 implements Serializable {
}

class Thing2 implements Serializable {

    Thing1 t1 = new Thing1();
}

class Thing3 implements Cloneable {
    @Override
    protected Thing3 clone() {
        try {
            return (Thing3) super.clone();
        } catch (CloneNotSupportedException e) {
            throw new RuntimeException(e);
        }
    }
}

class Thing4 implements Cloneable {
    private Thing3 t3 = new Thing3();

    @Override
    protected Thing4 clone() {
        Thing4 t4 = null;
        try {
            t4 = (Thing4) super.clone();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        t4.t3 = t3.clone();
        return t4;
    }
}

public class Compete {
    public static final int SIZE = 100000;

    public static void main(String[] args) throws Exception {
        Thing2[] a = new Thing2[SIZE];
        for (int i = 0; i < SIZE; i++) {
            a[i] = new Thing2();
        }

        Thing4[] b = new Thing4[SIZE];
        for (int i = 0; i < SIZE; i++) {
            b[i] = new Thing4();
        }

        long startTime = System.nanoTime();

        try (ByteArrayOutputStream buf = new ByteArrayOutputStream();
             ObjectOutputStream oos = new ObjectOutputStream(buf)) {
            for (Thing2 aItem : a) {
                oos.writeObject(aItem);
            }
            //获取副本
            try (ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(buf.toByteArray()))) {
                Thing2[] c = new Thing2[SIZE];
                for (int i = 0; i < SIZE; i++) {
                    c[i] = (Thing2) in.readObject();
                }
            }
            System.out.println("duplication via serialization: " + (System.nanoTime() - startTime) + "milliseconds");


            //clone

            long cloneTime = System.nanoTime();
            Thing4[] d = new Thing4[SIZE];
            for (int i = 0; i < SIZE; i++) {
                d[i] = b[i].clone();
            }
            System.out.println("duplication via cloning" + (System.nanoTime() - cloneTime) + " milliseconds");
        }


    }
}
